#include "mydata.h"
#include <signal.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <QDebug>
#include <QString>
#include <stdlib.h>


void *thread_func_Serial(void * _obj)
{
    MyData* obj = (MyData*)_obj;
    //获取新连接
loop:
    struct sockaddr_in peer;
    memset(&peer, 0, sizeof(peer));
    socklen_t len = sizeof(peer);
    obj->_client = accept(obj->_listen_sock, (struct sockaddr*)&peer, &len);
    emit obj->wlChanged();
    if(obj->_client == -1)
    {
        qDebug("accept failed");
        return (void*) -1;
    } else {
        qDebug("Connection succeeded");
    }
    char buf[128];
    int a, b, c, d;
    if (obj->_client) {
        while (true) {
            memset(buf , 0 , sizeof(buf));
            int len = read(obj->_client , buf , sizeof(buf));
            if (len <= 0) {
                qDebug("Connection disconnected");
                obj->_client = 0;
                emit obj->wlChanged();
                goto loop;
            }
            switch (buf[0]) {
            int com;
            case '1'://数据包
                sscanf(buf,"%d,%d,%d,%d,%d,", &com, &obj->wd, &obj->sd, &obj->gz, &obj->qt);
                qDebug() << buf;
                emit obj->dataChanged();
                break;
            case '2'://状态请求包
                emit obj->initChanged();
                qDebug() << buf;
                break;
            case '3'://开关状态包
                sscanf(buf,"%d,%d,%d,%d,%d", &com, &a, &b, &c, &d);
                qDebug() << buf;
                if (a != obj->wd_on_off) {
                    obj->wd_on_off = a;
                    emit obj->wonoffChanged();
                }
                if (b != obj->sd_on_off) {
                    obj->sd_on_off = b;
                    emit obj->sonoffChanged();
                }
                if (c != obj->gz_on_off) {
                    obj->gz_on_off = c;
                    emit obj->gonoffChanged();
                }
                if (d != obj->qt_on_off) {
                    obj->qt_on_off = d;
                    emit obj->qonoffChanged();
                }
                break;
            case '4'://智能控制开关包
                sscanf(buf,"%d,%d,%d,%d,%d", &com, &a, &b, &c, &d);
                qDebug() << buf;
                if (a != obj->znkz) {
                    obj->znkz = a;
                    emit obj->znChanged();
                }
                break;
            default:
                break;
            }
        }
    }

    return (void*) 0;
}

MyData::MyData(QObject *parent) : QObject(parent)
{
    this->_port = 8888;
    this->_client = 0;
    this->wd = 0;
    this->sd = 0;
    this->gz = 0;
    this->qt = 0;

    this->znkz = 0;

    this->wd_on_off = 0;
    this->sd_on_off = 0;
    this->gz_on_off = 0;
    this->qt_on_off = 0;

    InitServer();

    pthread_create(&thread, NULL, thread_func_Serial, this);
    pthread_detach(thread);
}

void MyData::myclose()
{
    close(_client);
    close(_listen_sock);
    _client = 0;
    emit this->wlChanged();
    pthread_cancel(this->thread);
}
void MyData::myaccept()
{
    InitServer();
    pthread_create(&thread, NULL, thread_func_Serial, this);
    pthread_detach(thread);
}
void MyData::myexit()
{
    exit(-1);
}

int MyData::getMyinit() const
{
    return myinit;
}

void MyData::setMyinit(int value)
{
    myinit = value;
}

int MyData::my_send(int com, int a, int b, int c, int d, int e, int f, int g, int h)
{
    char buf[128] = {0};
    //1智能调节 2设备控制
    if (e == -1) {
        if (com == 2) {
            this->gz_on_off = a;
            this->sd_on_off = b;
            this->wd_on_off = c;
            this->qt_on_off = d;
        }
        sprintf(buf, "%d,%d,%d,%d,%d", com, a, b, c, d);
        int ret = write(_client, buf, sizeof(buf));
        if (ret != sizeof(buf)) {
            qDebug("write fail");
            return -1;
        }
    } else {
        sprintf(buf, "%d,%d,%d,%d,%d,%d,%d,%d,%d", com, a, b, c, d, e, f, g, h);
        int ret = write(_client, buf, sizeof(buf));
        if (ret != sizeof(buf)) {
            qDebug("write fail");
            return -1;
        }
    }
    qDebug() << com << a << b << c << d;
    return 0;
}

int MyData::getZnkz() const
{
    return znkz;
}

void MyData::setZnkz(int value)
{
    znkz = value;
    emit znChanged();
}

int MyData::getClient() const
{
    return _client;
}

void MyData::setClient(int client)
{
    _client = client;
}


//初始化服务器
void MyData::InitServer()
{
    signal(SIGPIPE, SIG_IGN); //忽略SIGPIPE信号，防止写入时崩溃
    _listen_sock = socket(AF_INET, SOCK_STREAM, 0);
    if (_listen_sock < 0) { //创建套接字失败
        qDebug("socket error!");
        return;
    }
    //设置端口复用
    int opt = 1;
    setsockopt(_listen_sock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    struct sockaddr_in local;
    memset(&local, 0, sizeof(local));
    local.sin_family = AF_INET;
    local.sin_port = htons(_port);
    local.sin_addr.s_addr = INADDR_ANY;

    if (bind(_listen_sock, (struct sockaddr*)&local, sizeof(local)) < 0) { //绑定失败
        qDebug("bind error!");
        return;
    }

    if (listen(_listen_sock, 5) < 0) { //监听失败
        qDebug("listen error!");
        return;
    }
}

int MyData::getQt_on_off() const
{
    return qt_on_off;
}

void MyData::setQt_on_off(int value)
{
    qt_on_off = value;
}

int MyData::getGz_on_off() const
{
    return gz_on_off;
}

void MyData::setGz_on_off(int value)
{
    gz_on_off = value;
}

int MyData::getSd_on_off() const
{
    return sd_on_off;
}

void MyData::setSd_on_off(int value)
{
    sd_on_off = value;
}

int MyData::getWd_on_off() const
{
    return wd_on_off;
}

void MyData::setWd_on_off(int value)
{
    wd_on_off = value;
}

int MyData::getQt() const
{
    return qt;
}

void MyData::setQt(int value)
{
    qt = value;
}

int MyData::getGz() const
{
    return gz;
}

void MyData::setGz(int value)
{
    gz = value;
}

int MyData::getSd() const
{
    return sd;
}

void MyData::setSd(int value)
{
    sd = value;
}

int MyData::getWd() const
{
    return wd;
}

void MyData::setWd(int value)
{
    wd = value;
}
